﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Media;

namespace Mnuemonix {
    public abstract class GameScreen {

        protected enum BState { HOVER, UP, JUST_RELEASED, DOWN }

        public ContentManager content;
        public ScreenManager screenManager;
        public bool isHidden;// = true;
        public bool isDisabled;// = true;

        //buttonHandler
        protected const int NUMBER_OF_BUTTONS = 3, PREV_INDEX = 0, ABOUT_INDEX = 1, NEXT_INDEX = 2;
        protected int BUTTON_HEIGHT, BUTTON_WIDTH;
        protected Color background_color;
        protected Color[] button_color = new Color[NUMBER_OF_BUTTONS];
        protected Rectangle[] button_rectangle = new Rectangle[NUMBER_OF_BUTTONS];
        protected BState[] button_state = new BState[NUMBER_OF_BUTTONS];
        protected Texture2D[] button_texture = new Texture2D[NUMBER_OF_BUTTONS];
        protected double[] button_timer = new double[NUMBER_OF_BUTTONS];
        //mouse pressed and mouse just pressed
        protected bool mpressed, prev_mpressed = false;
        //mouse location in window
        protected int mx, my;
        protected double frame_time;

        public GameScreen(Microsoft.Xna.Framework.Game game)
        {
            this.content = new ContentManager(game.Services, "Content");
            game.IsMouseVisible = true;
        }

        public virtual void UnloadContent()
        {
            content.Unload();
        }

        public abstract void LoadContent();

        public abstract void Draw(GameTime gameTime);

        public abstract void Update(GameTime gameTime);

        protected Boolean hit_image_alpha(Rectangle rect, Texture2D tex, int x, int y)
        {
            if (rect.Y == 0 || rect.X == 0)
                return false;
            else
                return hit_image_alpha(0, 0, tex, tex.Width * (x - rect.X) /
                    rect.Width, tex.Height * (y - rect.Y) / rect.Height);
        }

        // wraps hit_image then determines if hit a transparent part of image 
        protected Boolean hit_image_alpha(float tx, float ty, Texture2D tex, int x, int y)
        {
            if (hit_image(tx, ty, tex, x, y))
            {
                uint[] data = new uint[tex.Width * tex.Height];
                tex.GetData<uint>(data);
                if ((x - (int)tx) + (y - (int)ty) *
                    tex.Width < tex.Width * tex.Height)
                {
                    return ((data[
                        (x - (int)tx) + (y - (int)ty) * tex.Width
                        ] &
                                0xFF000000) >> 24) > 20;
                }
            }
            return false;
        }

        // determine if x,y is within rectangle formed by texture located at tx,ty
        protected Boolean hit_image(float tx, float ty, Texture2D tex, int x, int y)
        {
            return (x >= tx &&
                x <= tx + tex.Width &&
                y >= ty &&
                y <= ty + tex.Height);
        }

        // determine state and color of button
        protected void update_buttons()
        {
            for (int i = 0; i < NUMBER_OF_BUTTONS; i++)
            {
                if (hit_image_alpha(
                    button_rectangle[i], button_texture[i], mx, my))
                {
                    button_timer[i] = 0.0;
                    if (mpressed)
                    {
                        // mouse is currently down
                        button_state[i] = BState.DOWN;
                        button_color[i] = Color.Blue;
                    }
                    else if (!mpressed && prev_mpressed)
                    {
                        // mouse was just released
                        if (button_state[i] == BState.DOWN)
                        {
                            // button i was just down
                            button_state[i] = BState.JUST_RELEASED;
                        }
                    }
                    else
                    {
                        button_state[i] = BState.HOVER;
                        button_color[i] = Color.LightBlue;
                    }
                }
                else
                {
                    button_state[i] = BState.UP;
                    if (button_timer[i] > 0)
                    {
                        button_timer[i] = button_timer[i] - frame_time;
                    }
                    else
                    {
                        button_color[i] = Color.White;
                    }
                }

                if (button_state[i] == BState.JUST_RELEASED)
                {
                    take_action_on_button(i);
                }
            }
        }

        public abstract void take_action_on_button(int i);

    }
}
